define(['angular'], function(angular) {
    angular.module('page_scroll_dir', [])
    .value('THROTTLE_MILLISECONDS', null)
    
    // 无限滚动
    .directive('infiniteScroll', ['$rootScope', '$window', '$timeout', 'THROTTLE_MILLISECONDS', function($rootScope, $window, $timeout, THROTTLE_MILLISECONDS) {
    return {
      scope: {
        infiniteScroll: '&',
        infiniteScrollContainer: '=',
        infiniteScrollDistance: '=',
        infiniteScrollDisabled: '=',
        infiniteScrollUseDocumentBottom: '='
      },
      link: function(scope, elem, attrs) {
        var changeContainer, checkWhenEnabled, container, handleInfiniteScrollContainer, handleInfiniteScrollDisabled, handleInfiniteScrollDistance, handleInfiniteScrollUseDocumentBottom, handler, immediateCheck, scrollDistance, scrollEnabled, throttle, useDocumentBottom;
        $window = angular.element($window);
        scrollDistance = null;
        scrollEnabled = null;
        checkWhenEnabled = null;
        container = null;
        immediateCheck = true;
        useDocumentBottom = false;
        handler = function() {
          var containerBottom, containerTopOffset, elementBottom, remaining, shouldScroll;
          if (container === $window) {
            containerBottom = container.height() + container.scrollTop();
            elementBottom = elem.offset().top + elem.height();
          } else {
            elementBottom = elem[0].scrollHeight - container.clientHeight - container.scrollTop;
          }
          if (useDocumentBottom) {
            elementBottom = $(document).height();
          }
          shouldScroll = elementBottom <= container.clientHeight * scrollDistance + 1;
          if (shouldScroll) {
            checkWhenEnabled = true;
//            if (scrollEnabled) {
              if (scope.$$phase || $rootScope.$$phase) {
                return scope.infiniteScroll();
              } else {
                return scope.$apply(scope.infiniteScroll);
              }
//            }
          } else {
            return checkWhenEnabled = false;
          }
        };
        throttle = function(func, wait) {
          var later, previous, timeout;
          timeout = null;
          previous = 0;
          later = function() {
            var context;
            previous = new Date().getTime();
            $timeout.cancel(timeout);
            timeout = null;
            func.call();
            return context = null;
          };
          return function() {
            var now, remaining;
            now = new Date().getTime();
            remaining = wait - (now - previous);
            if (remaining <= 0) {
              clearTimeout(timeout);
              $timeout.cancel(timeout);
              timeout = null;
              previous = now;
              return func.call();
            } else {
              if (!timeout) {
                return timeout = $timeout(later, remaining);
              }
            }
          };
        };
        if (THROTTLE_MILLISECONDS != null) {
          handler = throttle(handler, THROTTLE_MILLISECONDS);
        }
        scope.$on('$destroy', function() {
          return container.removeEventListener('scroll', handler, false);
        });
        handleInfiniteScrollDistance = function(v) {
          return scrollDistance = parseInt(v, 10) || 0;
        };
        scope.$watch('infiniteScrollDistance', handleInfiniteScrollDistance);
        handleInfiniteScrollDisabled = function(v) {
			if (v !== undefined) {
				  scrollEnabled = !v;
				  if (scrollEnabled && checkWhenEnabled) {
					checkWhenEnabled = false;
					return handler();
				  }
			}
        };
        scope.$watch('infiniteScrollDisabled', handleInfiniteScrollDisabled);
        handleInfiniteScrollUseDocumentBottom = function(v) {
          return useDocumentBottom = v;
        };
        scope.$watch('infiniteScrollUseDocumentBottom', handleInfiniteScrollUseDocumentBottom);
        handleInfiniteScrollUseDocumentBottom(scope.infiniteScrollUseDocumentBottom);
        changeContainer = function(newContainer) {
            container = newContainer;
		    return container.addEventListener('scroll', handler, false);
        };
//        changeContainer($window);
        handleInfiniteScrollContainer = function(newContainer) {
          if (newContainer) {
			  newContainer = newContainer.parentNode;
			  return changeContainer(newContainer);
		  }
        };
        scope.$watch('infiniteScrollContainer', handleInfiniteScrollContainer);
        if (attrs.infiniteScrollParent != null) {
          changeContainer(angular.element(elem.parent()));
        }
        if (attrs.infiniteScrollImmediateCheck != null) {
          immediateCheck = scope.$eval(attrs.infiniteScrollImmediateCheck);
        }
        return $timeout((function() {
          if (immediateCheck) {
//            return handler();
          }
        }), 0);
      }
    };
  }
])
	
});